package locks

import (
	"gitee.com/jade-virtual/kunlun/component/cache"
	"gitee.com/jade-virtual/kunlun/pkg/utils"
	"time"
)

var lockName = "locks:"
var lockExpire = 2
var unlockScript = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"

type RedisLock struct {
	store cache.Store
}

func NewRedisLock(store cache.Store) *RedisLock {
	return &RedisLock{store: store}
}

func (r *RedisLock) SyncLock(res string, goId uint64) {
	key := lockName + res
	value := utils.Uint64ToStr(goId)
	var checkValue string
	exist, err := r.store.Exist(key, checkValue)
	if err == nil && exist && value == checkValue {
		return
	}
	for {
		if r.store.SetNx(key, value, time.Duration(lockExpire)*time.Second) {
			break
		}
		time.Sleep(time.Duration(1) * time.Millisecond)
	}
}

func (r *RedisLock) GetLock(res string, goId uint64) bool {
	key := lockName + res
	value := utils.Uint64ToStr(goId)
	var checkValue string
	exist, err := r.store.Exist(key, checkValue)
	if err == nil && exist && value == checkValue {
		return true
	}
	return r.store.SetNx(key, value, time.Duration(lockExpire)*time.Second)
}

func (r *RedisLock) Unlock(res string, goId uint64) {
	key := lockName + res
	value := utils.Uint64ToStr(goId)
	var checkValue string
	exist, err := r.store.Exist(key, checkValue)
	if err == nil && exist && value == checkValue {
		keyList := make([]string, 0)
		keyList = append(keyList, key)
		_, _ = r.store.Eval(unlockScript, keyList, value)
	}
}
